﻿package scrn;
/*
 * Created on Nov 22, 2004
 *
 */
import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;

/**
 * An image divided into tiles
 * 
 * @author ath
 */
public class Test03 {

  /** The original image file */
  private BufferedImage originalImage;
  
  /** The sub-image tiles */
  private Image[][] tiles;

  /** The width in tiles */
  private int widthInTiles;

  /** The height in tiles */
  private int heightInTiles;

  /** The width of a tile */
  private int tileWidth;

  /** The height of a tile */
  private int tileHeight;

  /** The width of a tile in the unscaled image */
  private int unscaledTileWidth;

  /** The height of a tile in the unscaled image */
  private int unscaledTileHeight;

  /**
   * Construct a tiled image of size <code>width x height</code> from <code>image</code>
   * 
   * @param image The image to tile.
   * @param width The desired width in tiles.
   * @param height The desired height in tiles.
   */
  public Test03(BufferedImage image, int width, int height) {
    this.originalImage = image;
    this.tiles = new Image[width][height];
    this.widthInTiles = width;
    this.heightInTiles = height;

    unscaledTileWidth = tileWidth = image.getWidth() / width;
    unscaledTileHeight = tileHeight = image.getHeight() / height;
    
    for (int i = 0; i < widthInTiles; i++)
      for (int j = 0; j < heightInTiles; j++) {
        tiles[i][j] = image.getSubimage(i * tileWidth, j * tileHeight, tileWidth, tileHeight);
      }
  }

  /**
   * Get the sub-image for position (x,y). No bounds check is made.
   * 
   * @param x The x position of the required sub-image.
   * @param y The y position of the required sub-image.
   * @return The sub-image
   */
  public Image getTile(int x, int y) {
    return tiles[x][y];
  }

  /**
   * Returns the height of a tile in pixels.
   * 
   * @return The height of a tile in pixels.
   */
  public int getTileHeight() {
    return tileHeight;
  }

  /**
   * Returns the width of a tile in pixels.
   * 
   * @return The width of a tile in pixels.
   */
  public int getTileWidth() {
    return tileWidth;
  }

  /**
   * Returns the height of the tiled image, in tiles.
   * 
   * @return The height of the tiled image, in tiles.
   */
  public int getHeightInTiles() {
    return heightInTiles;
  }

  /**
   * Returns the width of the tiled image, in tiles.
   * 
   * @return The width of the tiled image, in tiles.
   */
  public int getWidthInTiles() {
    return widthInTiles;
  }

  /**
   * Given a pixel location in the image, return the co-ordinates of the
   * corresponding tile. If the given location is outside the image, this method
   * returns <code>null</code>.
   * 
   * @param x An x co-ordinate in terms of pixels
   * @param y A y co-ordinate in terms of pixels
   * @return A co-ordinate in terms of tiles or <code>null</code>
   */
  public Point getTileForLocation(int x, int y) {
    if (x > 0 && x <= tileWidth * widthInTiles && y > 0 && y < tileHeight * heightInTiles)
      return new Point(x / tileWidth, y / tileHeight);
    else
      return null;
  }
  /**
   * Scale the sub-images so that the complete image will fit within a rectangle
   * of the given width and height.
   * 
   * @param width The desired overall width.
   * @param height The desired overall height.
   */
  public void scaleTo(int width, int height) {
    tileWidth = width/widthInTiles;
    tileHeight = height/heightInTiles;
    for (int i = 0; i < widthInTiles; i++)
      for (int j = 0; j < heightInTiles; j++) {
        Image unscaledTile = originalImage.getSubimage(i * unscaledTileWidth, j * unscaledTileHeight, unscaledTileWidth, unscaledTileHeight);
        tiles[i][j] = unscaledTile.getScaledInstance(tileWidth, tileHeight, Image.SCALE_DEFAULT);
      }
  }

  /**
   * Rescale the sub-images back to their sizes in the original image.
   */
  public void scaleToOriginalSize() {
    scaleTo(originalImage.getWidth(), originalImage.getHeight());
  }

  /**
   * Change the number of tiles. The overall size of the image is unaffected
   * i.e. any previous scaling is preserved.
   * 
   * @param width The new width in tiles.
   * @param height The new height in tiles.
   */
  public void setGridSize(int width, int height) {
    int originalWidthInTiles = widthInTiles;
    int originalHeightInTiles = heightInTiles;
    tiles = new Image[width][height];
    widthInTiles = width;
    heightInTiles = height;
    
    unscaledTileWidth = originalImage.getWidth() / width;
    unscaledTileHeight = originalImage.getHeight() / height;

    scaleTo(originalWidthInTiles*tileWidth, originalHeightInTiles*tileHeight);
  }
}